package com.xtpt.disaster.common.ORACLE;

import com.xtpt.disaster.bean.DbnodeInfo;
import com.xtpt.disaster.common.ClientCmdBuilder;
import com.xtpt.disaster.common.JinCang.JinCangCmdBuilder;
import com.xtpt.disaster.common.PropertyConfig;
import com.xtpt.disaster.common.consts.DBEnum;
import com.xtpt.disaster.common.consts.DataTypeEnum;
import com.xtpt.disaster.common.consts.OSTypeEenum;
import com.xtpt.disaster.utils.ServerPathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class OracleCmdBuilder extends ClientCmdBuilder {
    @Autowired
    PropertyConfig config;
    @Autowired
    ServerPathUtil pathUtil;

    /**
     * 客户端操作系统类型
     */
    private OSTypeEenum osType;
    /**
     * 客户端节点信息
     */
    private DbnodeInfo clientDBNodeInfo;
    /**
     * 构造函数
     * @throws Exception 异常
     */
    public OracleCmdBuilder (){
        super();
    }

    public OracleCmdBuilder setOSType(OSTypeEenum osType) throws Exception
    {
        this.osType = osType;
        super.setOSType(this.osType);
        return this;
    }

    /**
     * 设置客户端节点信息
     * @param nodeInfo 客户端节点
     * @return this
     * @throws Exception
     */
    public OracleCmdBuilder initializeWithClientNode(DbnodeInfo nodeInfo) throws Exception {
        //设置客户端则初始化父类
        super.init();
        this.clientDBNodeInfo=nodeInfo;
        return this.setOSType(OSTypeEenum.getObject(nodeInfo.getNodeOsType()));
    }

    /**
     * 将服务端文件传递到客户端
     * @return this
     */
    public OracleCmdBuilder TransactionFilesToClient(List<String> filesName)
    {
        String useTool="scp -o StrictHostKeyChecking=no";
        String trans="%s -P %s %s@%s:%s %s%s";
        if(config.isScpNeedPass())
        {
            if(osType==OSTypeEenum.LINUX) {
                useTool = String.format("sshpass -p %s %s", config.getServerPassword(),useTool);
            }
            else
            {
                useTool = String.format("pscp -pw %s", config.getServerPassword());
            }
        }

        for (String file :filesName)
        {
            AddCmdWithNewGroup(
                    String.format(trans,
                            useTool,
                            config.getServerSshPort(),
                            config.getServerAccount(),
                            config.getServerIp(),
                            file,
                            clientDBNodeInfo.getNodeDbBackupPath(),
                            fileName(file))
            );
        }
        return this;
    }
    /**
     * 将客户端文件传递回到服务端
     * @return this
     */
    public OracleCmdBuilder TransactionFilesToServer(String clientFilePath,
                                                      String serverFilePath,
                                                      String serverPort)
    {
        if(serverPort==null)
        {
            serverPort="22";
        }
        String useTool="scp -o StrictHostKeyChecking=no";
        if(config.isScpNeedPass())
        {
            if(osType==OSTypeEenum.LINUX) {
                useTool = String.format("sshpass -p %s %s", config.getServerPassword(),useTool);
            }
            else
            {
                useTool = String.format("pscp -pw %s", config.getServerPassword());
            }
        }
        String trans="%s -P %s %s %s@%s:%s";
        String transCmd = String.format(trans,
                useTool,
                serverPort,
                clientFilePath,
                config.getServerAccount(),
                config.getServerIp(),
                serverFilePath);
        AddCmdWithNewGroupLn(transCmd);
        return this;
    }

    /**
     * 数据库备份
     * @param taskId
     * @param backFileName
     * @param FullOrIncrement
     * @param disc
     * @return
     * @throws Exception
     */
    public Map<String,String> dbBackUp(String taskId, String backFileName, String FullOrIncrement, String disc, String backFlag) throws Exception {
        Map<String,String> pathMap = new HashMap<>();
        String fullFileName = backFileName+config.getBackFileExtend();
        String serverFilePath=pathUtil.getServerFilePathDM(taskId,
                fullFileName,
                DataTypeEnum.DATABASE,
                DBEnum.ORACLE,
                FullOrIncrement);
        String exePath=combinePath(clientDBNodeInfo.getNodeDbBinPath(),"exp");
        String clientBackupFilePath=combinePath(clientDBNodeInfo.getNodeDbBackupPath(),
                fullFileName);
        String cmd=String.format("%s %s/%s@%s:%s/%s file=%s",
                exePath,
                clientDBNodeInfo.getNodeDbUsername(),
                clientDBNodeInfo.getNodeDbPassword(),
                clientDBNodeInfo.getNodeIp(),
                clientDBNodeInfo.getNodeDbPort(),
                clientDBNodeInfo.getNodeDbServiceName(),
                clientBackupFilePath);
        if(!FullOrIncrement.equalsIgnoreCase("FULL"))
        {
            throw new Exception("目前仅支持全量备份");
        }
        // 实际数据库备份流程
        AddCmdWithNewGroupLn(cmd).TransactionFilesToServer(clientBackupFilePath,
                serverFilePath,
                config.getServerSshPort());
        pathMap.put(serverFilePath,clientBackupFilePath);
        return pathMap;
    }

    /**
     * 数据库恢复
     * @param mainRestoreFilePathOnClient 要恢复的文件路径
     * @param allBackupFiles 所有相关路径（全量恢复时只有 @param mainRestoreFilePathOnClient）
     * @return
     */
    public OracleCmdBuilder dbRestore(String mainRestoreFilePathOnClient, List<String> allBackupFiles) {
        String exePath=combinePath(clientDBNodeInfo.getNodeDbBinPath(),"imp");
        String cmd=String.format("%s %s/%s@%s:%s/%s file=%s FULL=Y",
                exePath,
                clientDBNodeInfo.getNodeDbUsername(),
                clientDBNodeInfo.getNodeDbPassword(),
                clientDBNodeInfo.getNodeIp(),
                clientDBNodeInfo.getNodeDbPort(),
                clientDBNodeInfo.getNodeDbServiceName(),
                mainRestoreFilePathOnClient);
        TransactionFilesToClient(allBackupFiles);
        return AddCmdWithNewGroupLn(cmd);
    }

//////////////////////////////////////////////////// 如下重写父类方法
    /**
     * 新添加命令组并将命令加入到新组（自动加回车符）
     * @param cmd 命令字符串
     * @return this
     */
    public OracleCmdBuilder AddCmdLn(String cmd)
    {
        super.AddCmdLn(cmd);
        return this;
    }

    /**
     * 新添加命令组并将命令加入到新组（自动加回车符）
     * @param cmd 命令字符串
     * @return this
     */
    public OracleCmdBuilder AddCmd(String cmd)
    {
        super.AddCmd(cmd);
        return this;
    }
    /**
     * 新添加命令组并将命令加入到新组（自动加回车符）
     * @param cmd 命令字符串
     * @return this
     */
    public OracleCmdBuilder AddCmdWithNewGroupLn(String cmd)
    {
        super.AddCmdWithNewGroupLn(cmd);
        return this;
    }

    /**
     * 新添加命令组并将命令加入到新组（自动加回车符）
     * @param cmd 命令字符串
     * @return this
     */
    public OracleCmdBuilder AddCmdWithNewGroup(String cmd)
    {
        super.AddCmdWithNewGroup(cmd);
        return this;
    }


}
